<?php
/**
 * Ядро системы, статический класс которые предоставляет 
 * различные системные данные.
 * 
 * @author nrnwest@gmail.com
 *
 */
class Arm_Core
{
    /**
     * Состояние разработки.
     * @var string
     */
    const ENVIRONMENT_DEVELOPMENT = 'development';
    
    /**
     * Состояние тестирования.
     * @var string
     */
    const ENVIRONMENT_TESTING = 'testing';
    
    /**
     * Рабочие состояние.
     * @var string
     */
    const ENVIRONMENT_STAGING = 'staging';
    
    /**
     * Главный конфиг системы.
     *
     * @var Zend_Config_Ini
     */
    private static $_config = null;
    
    /**
     * Запрос к системе консольный или нет
     *
     * @var bool
     */
    private static $_cliRequest = null;

    /**
     * Флаг который даст, возможность задать cli запрос
     * принудительно. 
     * @var true|null
     */
    private static $_setCliRequest = null;

    /**
     * Вовзращает Главный конфиг системы.
     * в зависимости от режима работы приложения.
     * Если тестовый значит тестовый режим и так дальше.
     *
     * @return Zend_Config_Ini
     */
    public static function getConfigApplication ()
    {
        return self::_getConfig()->{self::getEnvironment()};
    }
    
    /**
     * вернет главный конфиг приложения.
     * 
     * @return Zend_Config_Ini
     */
    protected  static function _getConfig()
    {
       if (self::$_config === null) {
            self::$_config = new Zend_Config_Ini(APPLICATION_PATH . '/configs/application.ini');
        }
        return self::$_config;
    }
    
    /**
     * Вернет путь к директории application
     *
     * @return string путь к директории application, с конечным слешом.
     */
    public static function getPathApplication ()
    {
        return rtrim(APPLICATION_PATH, '\\/') . DIRECTORY_SEPARATOR;
    }
    
    /**
     * Вернет путь к директории временых файлов.
     */
    public static function getPathTemp()
    {
        return self::getPathApplication() . 'temp' . DIRECTORY_SEPARATOR;
    }

    /**
     * Вернет путь к директории библиотек.
     *
     *
     * @return string путь к директории library, с конечным слешом.
     */
    public static function getPathLibrary()
    {
        return rtrim(LIBRARY_PATH, '\\/') . DIRECTORY_SEPARATOR;
    }

    /**
     * Вернет путь к директории модуля 
     *
     * @param string имя директории модуля default|admin ...
     * @return string
     */
    public static function getPathModule ($module)
    {
        $module = strtolower(trim($module));
        return rtrim(MODULE_PATH, '\\/') . DIRECTORY_SEPARATOR . $module . DIRECTORY_SEPARATOR;
    }
    
    /**
     * Вернет путь к директории модулей.
     * 
     * @return string
     */
    public static function getPathModules()
    {
        return rtrim(MODULE_PATH, '\\/') . DIRECTORY_SEPARATOR;
    }
    
    /**
     * Путь к слоям
     *
     * @return string
     */
    public static function getPathLayouts ()
    {
        return self::getPathApplication() . 'layouts' . DIRECTORY_SEPARATOR;
    }

    /**
     * вернет полный путь к директории public
     *
     * @return string
     */
    public static function getPathPublicHtml()
    {
        return rtrim(PUBLIC_HTML_PATH, '\\/') . DIRECTORY_SEPARATOR;
    }
    
    /**
     * Путь к директории тестов.
     */
    public static function getPathTests()
    {
      return rtrim(dirname(APPLICATION_PATH), '\\/') . DIRECTORY_SEPARATOR . 'tests' . DIRECTORY_SEPARATOR;
    }

    /**
     * Вернет сосотояния приложения.
     *
     *
     * @return string development|testing|staging
     */
    public static function getEnvironment ()
    {
        return APPLICATION_ENV;
    }



    /**
     * Консольный запрос к системе или нет, если консольный
     * вернет true иначе false
     *
     * @param null|string $runType если указать http|cli будет принудельно
     *                             выставлен http запрос.
     * @return bool
     */
    public static function isCliRequest ()
    {

        if(self::$_setCliRequest === true) {
            return true;
        }

        if (false === array_key_exists('REQUEST_METHOD', $_SERVER)) {
            self::$_cliRequest = true;
        } else {
            self::$_cliRequest = false;
        }
        return self::$_cliRequest;
    }


    /**
     * Если нужно устанвить принудительно режим cli запроса вызваем данный
     * метод, а если нужно установить нормальный режим просто
     * вызываем данный метод с параметром $set указав false
     *
     * @param bool $set
     */
    public static function setCliRequest($set = true)
    {
        if($set === true) {
            self::$_setCliRequest = true;
        } else {
            self::$_setCliRequest = null;
        }
    }
    
    /**
     * Текущий обьект запроса
     * 
     * @return Zend_Controller_Request_Http
     */
    public static function getRequest()
    {
        return Zend_Controller_Front::getInstance()->getRequest();
    }
    
    
    /**
     * Метод ищет имя модуля в Request Uri, если находит, возвращает
     * имя модуля, иначе false.
     * Метод позволяет обнаружить имя вызываемого модуля, до закгрузки роутеров
     * ZF.
     * 
     * @return string|false
     */
    public static function getNameModuleRequestUri()
    {
        if(isset($_SERVER['REQUEST_URI']) === false) {
            return false;
        }
        $uri =  strtolower(trim($_SERVER['REQUEST_URI'], '/'));
        $array = explode('/', $uri);
        if($array[0] === '') {
            return false;
        }
        $module = $array[0];
        $path = MODULE_PATH . '/' . $module;
        if(is_dir($path) === false and isset($array[1]) === false) {
            return false;
        } else if(is_dir($path) === false) {
            $module = $array[1]; 
            $path   = MODULE_PATH . '/' . $array[1];
        }
        if(is_dir($path) === false) {
            return false;
        }
        return $module;
    }
    
    /**
     * Вернет разницу в секундах с точностью в 4 знаки между $timeStart и $timeEnd
     *
     * @param float $timeStart время старта microtime(1)
     * @param float $timeEnd время конца работы microtime(1)
     * @param float $precision количество знаков после запятой
     * @return float
     */
    public static function getTimeRun ($timeStart, $timeEnd, $precision=4)
    {  
        return round($timeEnd - $timeStart, $precision);
    }
}